package com.health.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.health.constant.Constants;
import com.health.model.User;

public class UserDAO extends HibernateDaoSupport
{
	private static final Log	log	= LogFactory.getLog(UserDAO.class);

	private SessionFactory		sessionFactory;

	private SimpleDateFormat	sdf	= new SimpleDateFormat("yyyy-MM-dd");

	public void insert(User u)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		tpl.save(u);
	}

	public void update(User u)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		tpl.update(u);
	}

	public void delete(User u)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		tpl.delete(u);
	}

	public User selectByPK(User u)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		String sql = "select U from User U where 1=1 ";
		if (u.getId() != null && u.getId() != "")
		{
			sql += " and U.id = '" + u.getId() + "'";
		}
		List userList = tpl.find(sql);

		if (userList.size() == 1)
		{
			return (User) userList.get(0);
		}
		else
		{
			return null;
		}
	}

	public User selectByPK(String id)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		String sql = "select U from User U where 1=1 and U.id = '" + id + "'";
		List userList = tpl.find(sql);
		if (userList.size() == 1)
		{
			return (User) userList.get(0);
		}
		else
		{
			return null;
		}

	}

	/**
	 * return all users in DB TABLE _USER without START & LIMIT params
	 */
	public List<User> selectListAll(User user)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		String sql = "select U from User U where 1= 1 ";
		if (null != user.getId() && !"".equals(user.getId()))
		{
			sql += " and U.id = '" + user.getId() + "'";// id
		}
		if (null != user.getName() && !"".equals(user.getName()))
		{
			sql += " and U.name = '" + user.getName() + "'";// name
		}
		if (null != user.getPassword() && !"".equals(user.getPassword()))
		{
			sql += " and U.password = '" + user.getPassword() + "'";// password
		}
		if (null != user.getGender() && !"".equals(user.getGender()))
		{
			sql += " and U.gender = " + user.getGender();// gender
		}
		if (null != user.getEmail() && !"".equals(user.getEmail()))
		{
			sql += " and U.email = '" + user.getEmail() + "'";// email
		}
		if (null != user.getRegistertime())
		{
			sql += " and U.registertime = '"
					+ sdf.format(user.getRegistertime()) + "'";// registertime
		}
		if (null != user.getBirthdate())
		{
			sql += " and U.birthdate = '" + sdf.format(user.getBirthdate())
					+ "'";// birthdate
		}
		if (null != user.getStartBirthdate())
		{
			sql += " and U.birthdate >= '"
					+ sdf.format(user.getStartBirthdate()) + "'";// startBithdate
		}
		if (null != user.getEndBirthdate())
		{
			sql += " and U.birthdate <= '" + sdf.format(user.getEndBirthdate())
					+ "'";// endBirthdate
		}
		if (null != user.getPermission() && !"".equals(user.getPermission()))
		{
			sql += " and U.permission = " + user.getPermission();// permission
		}
		if (null != user.getStatus() && !"".equals(user.getStatus()))
		{
			sql += " and U.status = " + user.getStatus();// status
		}
		List<User> userList = new ArrayList<User>();
		userList = tpl.find(sql);
		return userList;
	}

	/**
	 * select a result list include all of the user properties in querycondition
	 * with the START & LIMIT params
	 */
	public List<User> selectListPage(User user)
	{
		Session session = null;
		List<User> userList = new ArrayList<User>();
		int start = user.getStart();
		int limit = user.getLimit();
		String sql = "select U from User U where 1= 1 ";
		if (null != user.getId() && !"".equals(user.getId()))
		{
			sql += " and U.id = '" + user.getId() + "'";// id
		}
		if (null != user.getName() && !"".equals(user.getName()))
		{
			sql += " and U.name = '" + user.getName() + "'";// name
		}
		if (null != user.getPassword() && !"".equals(user.getPassword()))
		{
			sql += " and U.password = '" + user.getPassword() + "'";// password
		}
		if (null != user.getGender() && !"".equals(user.getGender()))
		{
			sql += " and U.gender = " + user.getGender();// gender
		}
		if (null != user.getEmail() && !"".equals(user.getEmail()))
		{
			sql += " and U.email = '" + user.getEmail() + "'";// email
		}
		if (null != user.getRegistertime())
		{
			sql += " and U.registertime = '"
					+ sdf.format(user.getRegistertime()) + "'";// registertime
		}
		if (null != user.getBirthdate())
		{
			sql += " and U.birthdate = '" + sdf.format(user.getBirthdate())
					+ "'";// birthdate
		}
		if (null != user.getStartBirthdate())
		{
			sql += " and U.birthdate >= '"
					+ sdf.format(user.getStartBirthdate()) + "'";// startBithdate
		}
		if (null != user.getEndBirthdate())
		{
			sql += " and U.birthdate <= '" + sdf.format(user.getEndBirthdate())
					+ "'";// endBirthdate
		}
		if (null != user.getPermission() && !"".equals(user.getPermission()))
		{
			sql += " and U.permission = " + user.getPermission();// permission
		}
		if (null != user.getStatus() && !"".equals(user.getStatus()))
		{
			sql += " and U.status = " + user.getStatus();// status
		}
		Query query = this.getSession().createQuery(sql);
		query.setFirstResult(start);
		query.setMaxResults(limit);
		userList = query.list();
		return userList;
	}

	public void loadUpdate(User u)
	{
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		User userLoaded = (User) session.load(User.class,
				"email1_test_2013-9-25_11:47:28");
		session.flush();
		session.getTransaction().commit();
		session.close();
	}

	/**
	 * batch insert
	 */
	public int insertBatch(List<User> userList)
	{
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		// count the amount of data which is inserted
		List<String> listCount = new ArrayList<String>();
		for (User u : userList)
		{
			String id = (String) session.save(u);
			listCount.add(id);

			// avoid out of memory
			if (listCount.size() % 10 == 0)
			{
				session.flush();
				session.clear();
				log.info("insert batch session cleared!");
			}
		}
		session.getTransaction().commit();
		log.info("insert batch amount is " + listCount.size());
		session.close();
		return listCount.size();
	}

	/**
	 * batch update
	 */
	/**
	 * public int updateBatch(List<User> userList) {
	 * log.info("------------UPDATE BATCH START-------------"); Session session
	 * = factory.openSession(); session.beginTransaction(); int updateCount = 0;
	 * for (User u : userList) { // the data in comein list is legal? User user
	 * = this.selectByPK(u); // data is invalid if (legalFlag == 0) { continue;
	 * } else if (legalFlag == 1) { ++updateCount; session.update(u); } else {
	 * log.warn("invalid data"); } } session.getTransaction().commit();
	 * session.close(); log.info("------------UPDATE BATCH END-------------");
	 * return updateCount; }
	 */

	public int updateBatch(List<String> idList)
	{
		log.info("------------UPDATE BATCH START-------------");
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		int updateCount = 0;
		for (int i = 0; i < idList.size(); i++)
		{
			// the data in comein list is legal?
			User user = this.selectByPK(idList.get(i));
			// data is invalid
			if (null == user)
			{
				continue;
			}
			else if (null != user)
			{
				++updateCount;
				session.update(user);
			}
		}
		session.getTransaction().commit();
		session.close();
		log.info("------------UPDATE BATCH END-------------");
		return updateCount;
	}

	/**
	 * delete batch
	 */
	public int deleteBatch(List<User> userList)
	{
		log.info("------------DELETE BATCH START-------------");
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		int deleteCount = 0;
		for (User u : userList)
		{
			session.delete(u);
			++deleteCount;
			if (deleteCount == 10)
			{
				session.flush();
				session.clear();
				log.info("delete batch session cleared");
			}
		}

		session.getTransaction().commit();
		session.close();
		log.info("delete batch amount is " + deleteCount);
		log.info("------------DELETE BATCH END-------------");
		return deleteCount;
	}

	/**
	 * login method
	 * 
	 * return a Object(User or String) need to judge
	 */
	public Object login(String email, String password)
	{
		HibernateTemplate tpl = new HibernateTemplate(getSessionFactory());
		String sql = "select U from User U where 1=1 and U.email = '" + email
				+ "'";
		List<User> userList = tpl.find(sql);
		if (userList.size() == 0)// account not exist
		{
			return Constants.EMAIL_NOT_FOUND;// email not exist
		}
		else if (userList.size() == 1)// account exist, judge loginCount and
										// password
		{
			if (userList.get(0).getLoginCount() >= Constants.LOGINCOUNT_LOCK)
			{
				return Constants.ACCOUNT_LOCKED;
			}
			String SQL = "select U from User U where 1=1 and U.email = '"
					+ email + "' and U.password = '" + password + "'";
			List<User> list = tpl.find(sql);
			if (list.size() == 0)
			{
				return Constants.PASSWORD_NOT_CORRECT;
				// return (User)(selectListAll(list.get(0))).get(0);// password
				// not correct
			}
			else
			{
				// return Constants.LOGIN_SUCCESS;
				return (User) list.get(0);// login success
			}
		}
		return null;
	}

}
